package cn.com.duiba.millionaire.center.biz.service.impl;

import cn.com.duiba.millionaire.center.api.constant.RedisKeyFactory;
import cn.com.duiba.millionaire.center.api.dto.MillionaireActivityDto;
import cn.com.duiba.millionaire.center.api.enums.ActivityTypeEnum;
import cn.com.duiba.millionaire.center.api.requestParam.MillionaireActivityRequestParam;
import cn.com.duiba.millionaire.center.biz.dao.MillionaireActivityDao;
import cn.com.duiba.millionaire.center.biz.dao.MillionaireMtAcRelationDao;
import cn.com.duiba.millionaire.center.biz.entity.MillionaireActivityEntity;
import cn.com.duiba.millionaire.center.biz.entity.MillionaireMainMeetingEntity;
import cn.com.duiba.millionaire.center.biz.entity.MillionaireMtAcRelationEntity;
import cn.com.duiba.millionaire.center.biz.service.MillionaireActivityService;
import cn.com.duiba.millionaire.center.biz.service.MillionaireMainMeetingService;
import cn.com.duiba.wolf.utils.BeanUtils;
import com.google.common.base.Joiner;
import com.google.common.collect.HashMultimap;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * Created by sty on 1/20/18.
 */
@Service
public class MillionaireActivityServiceImpl implements MillionaireActivityService {

    @Autowired
    private MillionaireActivityDao millionaireActivityDao;
    @Autowired
    private MillionaireMtAcRelationDao millionaireMtAcRelationDao;
    @Autowired
    private MillionaireMainMeetingService millionaireMainMeetingService;
    @Resource(name = "redisTemplate")
    private RedisTemplate<String, MillionaireActivityDto> redisTemplate;

    private String buildRedisKey(Long activityId) {
        return RedisKeyFactory.K007.toString() + activityId;
    }
    @Override
    public List<MillionaireActivityDto> getActivityByIds(List<Long> ids){
        return BeanUtils.copyList(millionaireActivityDao.findByIds(ids), MillionaireActivityDto.class);
    }

    @Override
    public String checkActivityAddMainMeeting(List<Long> ids,Integer actType) {
        if(CollectionUtils.isEmpty(ids)){
            return "分会场id不能为空";
        }
        //检查填写的活动id集合是否和选择类型相匹配
        List<Long> notActTypeIds = millionaireActivityDao.findIdsByActTypeAndIdIn(ids,actType);
        if(CollectionUtils.isNotEmpty(notActTypeIds)){
            return MessageFormat.format(ACTTYPE_MSG_TPL,Joiner.on(",").join(notActTypeIds), ActivityTypeEnum.findByType(actType).getDesc());
        }
        //已经被使用过的活动(开过奖的才算是使用过,在活动没开始前活动是可以被调整的,所以以开过奖算使用过)
        List<Long> alreadyUsedActIds = millionaireActivityDao.findIdsByAlreadyUseAndInId(ids);
        //关联过主会场的活动
        ids.removeAll(alreadyUsedActIds);
        List<MillionaireMtAcRelationEntity> mtAcRelations = null;
        //已与主会场关联的活动
        if(CollectionUtils.isNotEmpty(ids)){
            mtAcRelations = millionaireMtAcRelationDao.findByInActivityIds(ids);
        }

        return assembleErrorMsg(mtAcRelations,alreadyUsedActIds);
    }

    @Override
    public Integer countMillionaireActivityList(MillionaireActivityRequestParam param) {
        return millionaireActivityDao.findByPageCount();
    }

    @Override
    public List<MillionaireActivityDto> getMillionaireActivityList(MillionaireActivityRequestParam param) {
        List<MillionaireActivityEntity> entityList = millionaireActivityDao.findByPage(param.getPageNum(), param.getPageSize());
        if(CollectionUtils.isEmpty(entityList)){
            return Collections.emptyList();
        }

        return BeanUtils.copyList(millionaireActivityDao.findByPage(param.getPageNum(), param.getPageSize()), MillionaireActivityDto.class);
    }

    @Override
    public MillionaireActivityDto findMillionaireActivityById(Long id) {
        String key = buildRedisKey(id);
        MillionaireActivityDto millionaireActivityDto = redisTemplate.opsForValue().get(key);
        if (millionaireActivityDto != null) {
            return millionaireActivityDto;
        }
        MillionaireActivityDto resultActivity = BeanUtils.copy(millionaireActivityDao.findById(id), MillionaireActivityDto.class);
        if (resultActivity != null) {
            redisTemplate.opsForValue().set(key, resultActivity, 2, TimeUnit.MINUTES);
        }
        return resultActivity;
    }

    @Override
    public Boolean openOrDelete(Long id, Integer type) {
        MillionaireActivityDto millionaireActivity = findMillionaireActivityById(id);
        if (millionaireActivity == null) {
            return false;
        }

        int ret = 0;
        if (type == 1) {
            //开启
            if (Objects.equals(millionaireActivity.getOpenStatus(), MillionaireActivityDto.STATUS_OPEN)) {
                return false;
            }
            ret = millionaireActivityDao.updateStatusById(id, MillionaireActivityDto.STATUS_OPEN);
        }
        if (type == 2) {
            //关闭
            if (Objects.equals(millionaireActivity.getOpenStatus(), MillionaireActivityDto.STATUS_CLOSE)) {
                return false;
            }
            ret = millionaireActivityDao.updateStatusById(id, MillionaireActivityDto.STATUS_CLOSE);
        }
        if (type == 3) {
            ret = millionaireActivityDao.deleteById(id);
        }
        if (ret > 0) {
            redisTemplate.delete(buildRedisKey(id));
            return true;
        } else {
            return false;
        }
    }

    @Override
    public Boolean saveOrUpdateMillionaireActivity(MillionaireActivityDto dto) {
        if (dto.getId() == null) {
            //新增
            MillionaireActivityEntity activityEntity = millionaireActivityDao.insert(BeanUtils.copy(dto, MillionaireActivityEntity.class));
            return activityEntity.getId() != null;
        }
        //更新
        int ret = millionaireActivityDao.updateById(BeanUtils.copy(dto, MillionaireActivityEntity.class));
        if (ret > 0) {
            redisTemplate.delete(buildRedisKey(dto.getId()));
            return true;
        }
        return false;
    }

    @Override
    public int changeAlreadyUsed(Long id) {
        return millionaireActivityDao.changeAlreadyUsed(id,1);
    }

    @Override
    public List<MillionaireActivityDto> findAvailableActivity(Integer actType) {
        List<Long> actIds = millionaireActivityDao.findActivityIdByActype(actType);
        if(CollectionUtils.isEmpty(actIds)){
            return Collections.emptyList();
        }
        List<Long> relationActIds = millionaireMtAcRelationDao.findAllActivityIds();
        //排除已经关联的
        actIds.removeAll(relationActIds);
        if(CollectionUtils.isEmpty(actIds)){
            return Collections.emptyList();
        }
        List<MillionaireActivityEntity> activityEntities = millionaireActivityDao.findByIds(actIds);
        return BeanUtils.copyList(activityEntities,MillionaireActivityDto.class);
    }


    /**
     * 组装错误提示信息
     *
     * @param mtAcRelations
     * @return
     */
    private static final String ALREADY_USED_MSG_TPL = "分会场[{0}]使用过";
    private static final String RELATIONED_MSG_TPL = "分会场[{0}]已被添加在[{1}]主会场";
    private static final String ACTTYPE_MSG_TPL = "分会场[{0}]活动类型不是{1}";
    private String assembleErrorMsg(List<MillionaireMtAcRelationEntity> mtAcRelations,List<Long> alreadyUsedActIds){
        if(CollectionUtils.isEmpty(mtAcRelations) && CollectionUtils.isEmpty(alreadyUsedActIds)){
            return null;
        }
        List<String> errorMsgList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(alreadyUsedActIds)){
            String msg0 = Joiner.on(",").join(alreadyUsedActIds);
            errorMsgList.add(MessageFormat.format(ALREADY_USED_MSG_TPL,msg0));
        }
        if(CollectionUtils.isEmpty(mtAcRelations)){
            return Joiner.on(";").join(errorMsgList);
        }
        List<Long> mainMeetingIds = new ArrayList<>();
        HashMultimap<Long, Long> meetingIdToActIdsmap = HashMultimap.create();
        for(MillionaireMtAcRelationEntity entity : mtAcRelations){
            Long mainMeetingId = entity.getMeetingId();
            if(!mainMeetingIds.contains(mainMeetingId)){
                mainMeetingIds.add(entity.getMeetingId());
            }
            meetingIdToActIdsmap.put(mainMeetingId,entity.getActivityId());
        }
        Map<Long,String> meetingIdToTitleMap = findMainMeetingIdToTitle(mainMeetingIds);
        Set<Long> meetingIdSet = meetingIdToActIdsmap.keySet();
        for(Long meetingId : meetingIdSet){
            Set<Long> activityIds = meetingIdToActIdsmap.get(meetingId);
            String msg0 = Joiner.on(",").join(activityIds);
            String msg1 = meetingIdToTitleMap.get(meetingId);
            errorMsgList.add(MessageFormat.format(RELATIONED_MSG_TPL,msg0,msg1));
        }

        return Joiner.on(";").join(errorMsgList);
    }

    /**
     * 根据主会场id查询主会场对应的title的关系集合
     *
     * @param mainMeetingIds
     * @return
     */
    private Map<Long,String> findMainMeetingIdToTitle(List<Long> mainMeetingIds){
        List<MillionaireMainMeetingEntity> list = millionaireMainMeetingService.findByIds(mainMeetingIds);
        Map<Long,String> idToTitleMap = new HashMap<>();
        for(MillionaireMainMeetingEntity entity : list){
            idToTitleMap.put(entity.getId(),entity.getTitle());
        }
        return idToTitleMap;
    }
}
